/*!
* \file SelStrategyDefs.h
* \project	WonderTrader
*
* \author Wesley
* \date 2020/03/30
*
* \brief SEL策略定义文件
* \details 定义了SEL(Stock Selection)策略的基础类和策略工厂接口，提供选股策略开发的核心框架
*/
#pragma once
#include <string>
#include <stdint.h>

#include "../Includes/WTSMarcos.h"

NS_WTP_BEGIN
class WTSVariant;
class ISelStraCtx;
class WTSTickData;
struct WTSBarStruct;
NS_WTP_END

USING_NS_WTP;

/**
 * @class SelStrategy
 * @brief SEL策略基类
 * @details SEL(Stock Selection)策略的基础类，提供选股策略开发的基本框架。
 *          主要功能包括：
 *          - 策略生命周期管理
 *          - 股票选择逻辑实现
 *          - 定时调度执行
 *          - 市场数据监控
 *          - 多周期K线处理
 *          
 *          SEL策略主要用于中长期的股票选择，通常基于基本面分析、
 *          技术指标筛选、量化因子等进行股票池构建和股票轮换。
 *          策略运行频率通常为日级或周级，适合大资金的组合投资。
 */
class SelStrategy
{
public:
	/**
	 * @brief 构造函数
	 * @param id 策略实例ID
	 */
	SelStrategy(const char* id) :_id(id){}
	virtual ~SelStrategy(){}

public:
	/**
	 * @brief 获取策略名称
	 * @details 返回策略的唯一标识名称，用于策略识别和管理。
	 * @return const char* 策略名称
	 */
	virtual const char* getName() = 0;

	/**
	 * @brief 获取策略工厂名称
	 * @details 返回创建此策略的工厂名称，用于策略来源追踪。
	 * @return const char* 策略工厂名称
	 */
	virtual const char* getFactName() = 0;

	/**
	 * @brief 策略初始化
	 * @details 策略启动时的初始化方法，用于加载配置和设置初始状态。
	 * @param cfg 配置参数对象
	 * @return bool true表示初始化成功，false表示失败
	 */
	virtual bool init(WTSVariant* cfg){ return true; }

	/**
	 * @brief 获取策略实例ID
	 * @return const char* 策略实例ID
	 */
	virtual const char* id() const { return _id.c_str(); }

	/**
	 * @brief 策略初始化回调
	 * @details 策略框架初始化完成后的回调函数，在此进行策略特定的初始化操作。
	 * @param ctx SEL策略上下文指针
	 */
	virtual void on_init(ISelStraCtx* ctx){}

	/**
	 * @brief 交易会话开始回调
	 * @details 每个交易日会话开始时的回调函数，可以在此进行日初处理和股票池重新筛选。
	 * @param ctx SEL策略上下文指针
	 * @param uTDate 交易日期，格式为yyyyMMdd
	 */
	virtual void on_session_begin(ISelStraCtx* ctx, uint32_t uTDate) {}

	/**
	 * @brief 交易会话结束回调
	 * @details 每个交易日会话结束时的回调函数，可以在此进行日终处理和收益统计。
	 * @param ctx SEL策略上下文指针
	 * @param uTDate 交易日期，格式为yyyyMMdd
	 */
	virtual void on_session_end(ISelStraCtx* ctx, uint32_t uTDate) {}

	/**
	 * @brief 定时调度回调
	 * @details 按预设时间调度执行的回调函数，用于实现定时的选股逻辑和组合调整。
	 *          这是SEL策略的核心方法，通常在此实现股票筛选、权重分配、组合再平衡等逻辑。
	 * @param ctx SEL策略上下文指针
	 * @param uDate 当前日期，格式为yyyyMMdd
	 * @param uTime 当前时间，格式为HHMMss
	 */
	virtual void on_schedule(ISelStraCtx* ctx, uint32_t uDate, uint32_t uTime){}

	/**
	 * @brief Tick数据回调
	 * @details 实时tick数据到达时的回调函数，SEL策略通常不需要高频数据，此方法可选实现。
	 * @param ctx SEL策略上下文指针
	 * @param stdCode 标准合约代码
	 * @param newTick 新的tick数据
	 */
	virtual void on_tick(ISelStraCtx* ctx, const char* stdCode, WTSTickData* newTick){}

	/**
	 * @brief K线数据回调
	 * @details K线数据更新时的回调函数，用于监控股票价格变化和技术指标计算。
	 *          SEL策略通常使用日K线或更长周期的K线数据进行分析。
	 * @param ctx SEL策略上下文指针
	 * @param stdCode 标准合约代码
	 * @param period K线周期，如"d1"、"w1"、"m1"等
	 * @param newBar 新的K线数据
	 */
	virtual void on_bar(ISelStraCtx* ctx, const char* stdCode, const char* period, WTSBarStruct* newBar){}

protected:
	std::string _id;	///< 策略实例ID
};

//////////////////////////////////////////////////////////////////////////
/// @brief SEL策略枚举回调函数类型
/// @param factName 工厂名称
/// @param straName 策略名称
/// @param isLast 是否为最后一个策略
typedef void(*FuncEnumSelStrategyCallback)(const char* factName, const char* straName, bool isLast);

/**
 * @class ISelStrategyFact
 * @brief SEL策略工厂接口
 * @details SEL策略工厂的核心接口，负责选股策略的创建、删除和管理。
 *          主要功能包括：
 *          - 策略实例创建和销毁
 *          - 策略类型枚举
 *          - 工厂标识管理
 *          
 *          策略工厂采用工厂模式设计，支持动态加载和卸载策略模块，
 *          为选股策略系统提供灵活的扩展机制。特别适用于需要
 *          快速开发和部署不同选股逻辑的量化投资环境。
 */
class ISelStrategyFact
{
public:
	ISelStrategyFact(){}
	virtual ~ISelStrategyFact(){}

public:
	/**
	 * @brief 获取工厂名称
	 * @details 返回策略工厂的唯一标识名称。
	 * @return const char* 工厂名称
	 */
	virtual const char* getName() = 0;

	/**
	 * @brief 枚举策略
	 * @details 枚举工厂支持的所有策略类型，通过回调函数返回策略信息。
	 * @param cb 枚举回调函数，用于接收策略信息
	 */
	virtual void enumStrategy(FuncEnumSelStrategyCallback cb) = 0;

	/**
	 * @brief 根据策略名称创建策略实例
	 * @details 根据指定的策略名称和实例ID创建新的SEL策略实例。
	 * @param name 策略名称
	 * @param id 策略实例ID
	 * @return SelStrategy* 策略实例指针，创建失败返回nullptr
	 */
	virtual SelStrategy* createStrategy(const char* name, const char* id) = 0;

	/**
	 * @brief 删除策略实例
	 * @details 销毁指定的策略实例并释放相关资源。
	 * @param stra 要删除的策略实例指针
	 * @return bool true表示删除成功，false表示失败
	 */
	virtual bool deleteStrategy(SelStrategy* stra) = 0;
};

/// @brief 创建SEL策略工厂函数指针类型
typedef ISelStrategyFact* (*FuncCreateSelStraFact)();

/// @brief 删除SEL策略工厂函数指针类型
typedef void(*FuncDeleteSelStraFact)(ISelStrategyFact* &fact);
